import React, { Component } from 'react'
import {
  Button,
  Checkbox,
  Collapse,
  DatePicker,
  Form,
  Input,
  InputNumber,
  message,
  Radio,
  Select,
  TimePicker,
  Tooltip,
  Row,
  Col,
  Switch,
} from 'antd'
import { history } from '@umijs/max'
import moment from 'moment'
import styles from './index.less'
import { offlineSave } from './api'
import {
  gethours, getminute, getmonth, getWeek,
} from '@/utils/helper'

const { Option } = Select
const { Panel } = Collapse

class Configuration extends Component {
  constructor(props) {
    super(props)
    this.state = {
      cycle: undefined,
      open: false,
      pgText: 0,
    }
    this.configurationForm = React.createRef()
  }

  componentWillReceiveProps(nextProps) {
    if (nextProps.data !== this.props.data) {
      const data = nextProps.data
      if (!data.id) {
        this?.configurationForm?.current?.setFieldsValue({
          effectiveDate: [
            moment(new Date().toLocaleDateString(), 'YYYY-MM-DD'),
            null,
          ],
        })
        return null
      }

      const endDate = data.schedule.effectiveDateEnd === '9999-12-30' ? null : data.schedule.effectiveDateEnd

      this.setState({
        cycle: data.schedule.cycle,
        pgText: data.pgText,
      }, () => {
        this.configurationForm && this.configurationForm.current.setFieldsValue({
          dataReplaceRuleId: data.dataReplaceRuleId,
          isTruncate: !!data.isTruncate,
          errorNumLimit: data.errorNumLimit,
          fetchSize: data.fetchSize,
          batchSize: data.batchSize,
          channel: data.channel,
          splitKey: data.splitKey,
          cycleDependence: data.schedule.cycleDependence,
          cycle: (data.schedule.cycle || data.schedule.cycle === 0) ? String(data.schedule.cycle) : undefined,
          effectiveDate: [
            moment(data.schedule.effectiveDateStart || new Date().toLocaleDateString(), 'YYYY-MM-DD'),
            // moment(data.schedule.effectiveDateEnd, 'YYYY-MM-DD'),
            endDate && moment(endDate, 'YYYY-MM-DD') || null,
          ],
          pgText: data.pgText,
          openSchedule: !!data.openSchedule,
          startTime: String(data.schedule.cycle) === '0' || String(data.schedule.cycle) === '1' || String(data.schedule.cycle) === '2'
            ? moment(
              `${data.schedule.startTimeHour}:${data.schedule.startTimeMin}`,
              'HH:mm',
            ) : [
              moment(
                `${data.schedule.startTimeHour}:${data.schedule.startTimeMin}`,
                'HH:mm',
              ),
              moment(
                `${data.schedule.endTimeHour}:${data.schedule.endTimeMin}`,
                'HH:mm',
              ),
            ],
          execPoint: data.schedule.execPoint && data.schedule.execPoint.split(','),
        })
      })
    }
    return null
  }

  offlineSave = () => {
    const { data } = this.props
    this.configurationForm.current.validateFields().then(values => {
      const effectiveDateStart = values?.effectiveDate?.[0]?.format('YYYY-MM-DD')
      const effectiveDateEnd = values?.effectiveDate?.[1]?.format('YYYY-MM-DD') || '9999-12-30'

      let startTime = null; let endTime = null
      if (values.cycle === '0' || values.cycle === '1' || values.cycle === '2') {
        startTime = values.startTime.format('HH:mm').split(':')
      } else if (values.cycle === '3' || values.cycle === '4') {
        startTime = values.startTime[0].format('HH:mm').split(':')
        endTime = values.startTime[1].format('HH:mm').split(':')
      }

      const {
        isTruncate, dataReplaceRuleId, errorNumLimit, fetchSize, batchSize, channel, splitKey, openSchedule,
        pgText,
      } = values

      if (!effectiveDateStart && openSchedule) {
        message.warn('生效日期的开始时间不能为空')
        return null
      }

      this.setState({
        loading: true,
      })

      offlineSave({
        ...data,
        isTruncate: isTruncate ? 1 : 0,
        dataReplaceRuleId,
        errorNumLimit,
        fetchSize,
        batchSize,
        channel,
        splitKey,
        pgText: pgText ? 1 : 0,
        openSchedule: openSchedule ? 1 : 0,
        schedule: {
          effectiveDateStart,
          effectiveDateEnd,
          cycle: values.cycle,
          startTimeHour: startTime ? startTime[0] : '',
          startTimeMin: startTime ? startTime[1] : '',
          endTimeHour: endTime ? endTime[0] : '',
          endTimeMin: endTime ? endTime[1] : '',
          cycleDependence: values.cycleDependence || values.cycleDependence === 0 ? values.cycleDependence : '',
          execPoint: Array.isArray(values.execPoint)
            ? values.execPoint
              .sort((a, b) => a - b)
              .join()
            : values.execPoint,
        },
      }).then((res) => {
        if (res.status === 200) {
          message.success(res.msg)
          history.push('/dataIntegrate/offline/manager')
        } else {
          message.error(res.msg)
        }
        this.setState({
          loading: false,
        })
      })
      return null
    })
  }

  valuesChange = (value, allValues) => {
    const key = Object.keys(value)[0]
    console.log(value, key, allValues)
    if (key === 'cycle') {
      this.configurationForm && this.configurationForm.current.setFieldsValue({
        startTime: undefined,
        execPoint: undefined,
      })
      this.setState({
        cycle: Number(allValues.cycle),
      })
    }
    if (key === 'pgText') {
      this.setState({
        pgText: value.pgText,
      })
    }
  }

  handleOpenChange = (open) => {
    this.setState({
      open,
    })
  }

  handleDate = () => {
    const { currentDate } = this.state
    const { effectiveDate } = this.configurationForm.current.getFieldsValue(['effectiveDate'])

    this.setState({ open: false })
    this.configurationForm.current.setFieldsValue({
      effectiveDate: [currentDate?.[0] || effectiveDate?.[0], null],
    })
  }

  handleCalendarChange = (dates) => {
    this.setState({
      currentDate: dates,
    })
  }

  render() {
    const { cycle, pgText } = this.state
    const { targetDsType } = this.props?.data || {}
    const formItemLayout = {
      labelCol: { span: 4 },
      wrapperCol: { span: 20 },
    }

    return (
      <div className={styles.configuration} style={{ ...this.props.style }}>
        <Form
          className={styles.form}
          colon={false}
          {...formItemLayout}
          onValuesChange={this.valuesChange}
          ref={this.configurationForm}
        >
          <Form.Item>
            <div className={styles.column}>同步配置</div>
          </Form.Item>
          <Row>
            <Col span={9} offset={3}>
              <Form.Item
                label=" "
                name="isTruncate"
                valuePropName="checked"
              >
                <Checkbox>同步前清空历史数据</Checkbox>
              </Form.Item>
            </Col>
          </Row>
          {
            targetDsType === 'PostgreSQL' && (
              <Row>
                <Col span={9} offset={3}>
                  <Form.Item
                    label=" "
                    name="pgText"
                    valuePropName="checked"
                  >
                    <Checkbox>开启文件写入模式</Checkbox>
                  </Form.Item>
                </Col>

                <Col span={4}>
                  <div className="ant-col ant-col-4" style={{ paddingTop: 3 }}>
                    <Tooltip
                      placement="top"
                      title={
                        <p>建议勾选同步前清空，防止主键冲突</p>
                      }
                    >
                      <i className="iconfont icon-yiwentishi" />
                    </Tooltip>
                  </div>
                </Col>
              </Row>
            )
          }
          {
            !pgText && (
              <>
                <Form.Item
                  label="写入模式"
                  name="dataReplaceRuleId"
                  rules={[{ required: true, message: '请选择写入模' }]}
                >
                  <Radio.Group>
                    {targetDsType === 'Hive' ? <Radio value={1}>覆盖（Insert Overwrite）</Radio> : null}
                    {targetDsType === 'Hive' ? <Radio value={2}>追加（Insert Into）</Radio> : null}
                    {targetDsType !== 'Hive' ? <Radio value={5}>主键冲突，替换原有数据</Radio> : null}
                    {targetDsType !== 'Hive' ? <Radio value={6}>主键冲突，丢弃新数据</Radio> : null}
                  </Radio.Group>
                </Form.Item>
                <Form.Item
                  className={styles.check_bar}
                  label="脏数据限制"
                  style={{ marginTop: '.1rem' }}
                  initialValue={10}
                  name="errorNumLimit"
                  rules={[{
                    required: false,
                    // eslint-disable-next-line prefer-regex-literals
                    // pattern: new RegExp('/[0-9]/', ''),
                    // message: '请选择脏数据限制',
                  }]}
                >
                  <InputNumber min={0} addonBefore="单次同步失败记录数超过" addonAfter="条则任务结束" />
                </Form.Item>
                <Collapse ghost>
                  <Panel header="高级配置" key="1" forceRender>
                    <Form.Item
                      label={
                        <span>
                          每次读取数据条数（fetchSize）
                          <Tooltip title={
                            <div>
                              <p>该值决定了平台每次获取数据的条数,数值越大越能够提升数据抽取性能，但应避免过大（2048）造成进程宕机。</p>
                            </div>
                          }
                          >
                            <i className="iconfont icon-yiwentishi" />
                          </Tooltip>
                        </span>
                      }
                      wrapperCol={{ span: 12, offset: 6 }}
                      initialValue={500}
                      name="fetchSize"
                    >
                      <InputNumber min={0} />
                    </Form.Item>
                    <Form.Item
                      label={
                        <span>
                          每次写入数据条数（batchSize）
                          <Tooltip title={
                            <div>
                              <p>该值决定了平台每次写入数据的条数，数值越大能够提升平台数据吞吐量，但应避免过大（10000）造成进程宕机。</p>
                            </div>
                          }
                          >
                            <i className="iconfont icon-yiwentishi" />
                          </Tooltip>
                        </span>
                      }
                      wrapperCol={{ span: 12, offset: 6 }}
                      initialValue={2000}
                      name="batchSize"
                    >
                      <InputNumber min={0} />
                    </Form.Item>
                    <Form.Item
                      label={
                        <span>
                          并发数（channel）
                          <Tooltip title={
                            <div>
                              <p>该值是数据调度进程数，提高进程数可以减少数据同步时间。但应避免过大（10）造成进程宕机。</p>
                            </div>
                          }
                          >
                            <i className="iconfont icon-yiwentishi" />
                          </Tooltip>
                        </span>
                      }
                      wrapperCol={{ span: 12, offset: 6 }}
                      initialValue={5}
                      name="channel"
                    >
                      <InputNumber min={0} />
                    </Form.Item>
                    <Form.Item
                      label={
                        <span>
                          切片字段（splitKey）
                          <Tooltip title={
                            <div>
                              <p>该字段作为读取来源表时进行切分并行读取的依赖字段，优先选主键或唯一字段，支持字符串类型和整型；与并发数联合使用才有效。</p>
                            </div>
                          }
                          >
                            <i className="iconfont icon-yiwentishi" />
                          </Tooltip>
                        </span>
                      }
                      wrapperCol={{ span: 12, offset: 6 }}
                      name="splitKey"
                    >
                      <Input />
                    </Form.Item>
                  </Panel>
                </Collapse>
              </>
            )
          }
          <div className={styles.column}>调度配置
            <Form.Item
              name="openSchedule"
              valuePropName="checked"
              style={{ display: 'inline-block', marginLeft: '10px' }}
            >
              <Switch checkedChildren="开启" unCheckedChildren="关闭" />
            </Form.Item>
          </div>
          <Form.Item shouldUpdate noStyle>
            {(form) => form.getFieldValue('openSchedule') && (
              <>
                <Form.Item
                  label="生效日期"
                  name="effectiveDate"
                >
                  <DatePicker.RangePicker
                    open={this.state.open}
                    style={{ width: '100%' }}
                    placeholder={['开始时间', '无限制']}
                    onOpenChange={this.handleOpenChange}
                    renderExtraFooter={() => (<div className={styles.extra_footer_wrap}><span onClick={this.handleDate}>无限制</span></div>)}
                    onCalendarChange={this.handleCalendarChange}
                  />
                </Form.Item>
                <Form.Item
                  label="调度周期"
                  name="cycle"
                  rules={[{ required: true, message: '请选择调度周期' }]}
                >
                  <Select placeholder="请选择调度周期">
                    <Option key={0}>月</Option>
                    <Option key={1}>周</Option>
                    <Option key={2}>天</Option>
                    <Option key={3}>小时</Option>
                    <Option key={4}>分钟</Option>
                  </Select>
                </Form.Item>
                {cycle === 0 || cycle === 1 || cycle === 2
                  ? (
                    <Form.Item
                      label="执行时间"
                      name="startTime"
                      rules={[{ required: true, message: '请选择执行时间' }]}
                    >
                      <TimePicker style={{ width: '100%' }} format="HH:mm" />
                    </Form.Item>
                  ) : null}
                {cycle === 3 || cycle === 4 ? (
                  <Form.Item
                    label="执行时间"
                    name="startTime"
                    rules={[{ required: true, message: '请选择执行时间' }]}
                  >
                    <TimePicker.RangePicker style={{ width: '100%' }} format="HH:mm" />
                  </Form.Item>
                  ) : null}
                {cycle === 0 || cycle === 1 || cycle === 3 || cycle === 4 ? (
                  <Form.Item
                    label="调度间隔"
                    name="execPoint"
                    rules={[{ required: true, message: '请选择调度间隔' }]}
                  >
                    <Select mode={cycle === 0 || cycle === 1 ? 'multiple' : 'none'} placeholder="请选择调度间隔">
                      {cycle === 0
                          && getmonth().map((item) => (
                            <Option name={item.name} key={item.id}>
                              {item.name}
                            </Option>
                          ))}
                      {cycle === 1
                          && getWeek().map((item) => (
                            <Option name={item.name} key={item.id}>
                              {item.name}
                            </Option>
                          ))}
                      {cycle === 4
                          && getminute().map((item) => (
                            <Option name={item.name} key={item.id}>
                              {item.name}
                            </Option>
                          ))}
                      {cycle === 3
                          && gethours().map((item) => (
                            <Option name={item.name} key={item.id}>
                              {item.name}
                            </Option>
                          ))}
                    </Select>
                  </Form.Item>
                  ) : null}
                <Form.Item
                  label="跨周期依赖"
                  name="cycleDependence"
                  rules={[{ required: true, message: '请选择跨周期依赖' }]}
                >
                  <Radio.Group>
                    <Radio value={0}>不依赖上一周期</Radio>
                    <Radio value={1}>等待上一周期结束</Radio>
                  </Radio.Group>
                </Form.Item>
              </>
            )}
          </Form.Item>
        </Form>
        <div className={styles.edit_footer}>
          <Button onClick={() => { history.push('/dataIntegrate/offline/manager') }} className={styles.edit_btn}>取消</Button>
          <Button
            className={styles.edit_btn}
            onClick={() => {
              this.props.returnStep(1)
            }}
            type="primary"
          >上一步
          </Button>
          <Button loading={this.state.loading} onClick={this.offlineSave} className={styles.edit_btn} type="primary">确认</Button>
        </div>
      </div>
    )
  }
}

export default Configuration
